
#ifndef  _RADIX_ARCHAISM_STRING_H_
#define  _RADIX_ARCHAISM_STRING_H_

#include <Archaism/Header.h>
#include <vector>
#include <list>
#include <map>
#include <sstream>
#include <cstdarg>

_BeginNamespace(Radix)

typedef std::list<String> StringList;
typedef std::vector<String> StringVector;
typedef std::map<String, String> StringMap;

#if(_RADIX_STRINGTYPE == _RADIX_STRINGTYPE_MBS)
	typedef std::stringstream StringStream;	
#else
	typedef std::wstringstream StringStream;
#endif//(_RADIX_STRINGTYPE == _RADIX_STRINGTYPE_MBS)

class StringUtil
{
public:
/*
============================================================================================
==== StringUtil -- codec functions
============================================================================================
*/
	static std::string unicodeToUtf8(const std::wstring& unicodeStr, bool bom);
	static std::wstring utf8ToUnicode(const std::string& utf8Str, bool bom);
/*
============================================================================================
==== StringUtil -- frequently used functions
============================================================================================
*/
	static String fromUtf8(const std::string& str);
	static std::string toUtf8(const String& str);
	static String fromUnicode(const std::wstring& str);
	static std::wstring toUnicode(const String& str);
	static bool contains(const String& str1, const String& str2);
	static bool containsOne(const String& str, const StringVector& strs);
	static bool containsAll(const String& str, const StringVector& strs);
	static bool startsWith(const String& str1, const String& str2);
	static bool startsWith(const String& str, const StringVector& strs);
	static bool endsWith(const String& str1, const String& str2);
	static bool endsWith(const String& str, const StringVector& strs);
	static String toUpper(const String& str);
	static String toLower(const String& str);
	static String reverse(const String& str);
	static String substr(const String& str, String::size_type start, String::size_type len = String::npos);
	static String left(const String& str, String::size_type len);
	static String right(const String& str, String::size_type len);
	static String replace(const String& str, const String& str1, const String& str2);
	static String replace(const String& str, const StringMap& nameValues);
	static String trim(const String& str);
	static String trimLeft(const String& str);
	static String trimRight(const String& str);
	static StringVector split(const String& str, const String& delim);
/*
============================================================================================
==== StringUtil -- format functions
============================================================================================
*/
	static void format(String& result, const String::value_type* fmt, va_list ap);
	static String format(const String::value_type* fmt, ...);
/*
============================================================================================
==== StringUtil -- type casting functions
============================================================================================
*/
	template<typename T>
	inline static String valueToString(T value)
	{
		StringStream stream;
		stream << value;
		return stream.str();
	}
	template<>
	inline static String valueToString<bool>(bool value)
	{
		return value ? _T("true") : _T("false");
	}

	template<typename T>
	inline static T stringToValue(const String& str)
	{
		T value = 0;
		StringStream stream(str);
		stream >> value;
		return value;
	}
	template<>
	inline static bool stringToValue<bool>(const String& str)
	{
		return (str == _T("true") || 
			str == _T("True") || 
			str == _T("TRUE") || 
			str == _T("1")) ?
			true : false;
	}
};

/*
============================================================================================
==== StringValue -- type casting class
============================================================================================
*/
class StringValue
{
public:
	StringValue(const StringValue& var);
	StringValue(const String& value);
	StringValue(short value = 0);
	StringValue(ushort value);
	StringValue(int value);
	StringValue(uint value);
	StringValue(long value);
	StringValue(ulong value);
	StringValue(longlong value);
	StringValue(ulonglong value);
	StringValue(float value);
	StringValue(double value);
	StringValue(longdouble value);
	StringValue(bool value);

public:
	StringValue& operator=(const StringValue& var);
	StringValue& operator=(const String& value);
	StringValue& operator=(const String::value_type* value);
	StringValue& operator=(short value);
	StringValue& operator=(ushort value);
	StringValue& operator=(int value);
	StringValue& operator=(uint value);
	StringValue& operator=(long value);
	StringValue& operator=(ulong value);
	StringValue& operator=(longlong value);
	StringValue& operator=(ulonglong value);
	StringValue& operator=(float value);
	StringValue& operator=(double value);
	StringValue& operator=(longdouble value);
	StringValue& operator=(bool value);

	operator const String&() const;
	operator short() const;
	operator ushort() const;
	operator int() const;
	operator uint() const;
	operator long() const;
	operator ulong() const;
	operator longlong() const;
	operator ulonglong() const;
	operator float() const;
	operator double() const;
	operator longdouble() const;
	operator bool() const;

public:
	const String& string() const
	{
		return (const String&)(*this);
	}
	
	template<typename T>
	T value() const
	{
		return (T)(*this);
	}

private:
	String mValue;
};

typedef std::list<StringValue> StringValueList;
typedef std::vector<StringValue> StringValueVector;
typedef std::map<String, StringValue> StringValueMap;

_EndNamespace(Radix)

#endif//_RADIX_ARCHAISM_STRING_H_
